package com.gitee.qdbp.general.thirdpart.biz.amap.service;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.ibatis.ognl.Ognl;
import org.apache.ibatis.ognl.OgnlException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gitee.qdbp.able.result.ResponseMessage;
import com.gitee.qdbp.able.result.ResultCode;
import com.gitee.qdbp.tools.http.ConfigHttpHandler;
import com.gitee.qdbp.tools.http.HostUrlConfig;
import com.gitee.qdbp.tools.http.HostUrlConfig.KeyedHttpUrl;
import com.gitee.qdbp.tools.http.HttpExecutor;
import com.gitee.qdbp.tools.http.HttpTools.HttpFormImpl;
import com.gitee.qdbp.tools.http.HttpUrl;
import com.gitee.qdbp.tools.http.RemoteServiceException;
import com.gitee.qdbp.tools.utils.VerifyTools;

// https://lbs.amap.com/api/webservice/summary
public class AmapHttpExecutor extends HttpExecutor {

    /** 空字符串会以空数组的形式返回 **/
    private static Pattern EMPTY_ARRAY = Pattern.compile("\\[\\]");

    public AmapHttpExecutor(HostUrlConfig config) {
        super(config, new HttpFormImpl(), new AmapHandler());
    }

    private static class AmapHandler extends ConfigHttpHandler {

        public <T> Map<String, Object> fillBaseParams(HttpUrl hurl, Map<String, T> params) {
            Map<String, Object> map = new HashMap<>();
            if (VerifyTools.isNotBlank(params)) {
                map.putAll(params);
            }
            map.put("output", "JSON");
            map.put("key", config.getString("amap.app.key"));
            return map;
        }

        @Override
        public ResponseMessage parseResult(HttpUrl hurl, String string) throws RemoteServiceException, Exception {
            string = EMPTY_ARRAY.matcher(string).replaceAll("null");

            // 响应报文是一个平级结构
            // { status:int, infocode:int }
            // status是系统异常, 1=成功; infocode是业务异常, 10000=成功
            JSONObject json = JSON.parseObject(string);
            String status = json.getString("status");
            if (!status.equals(config.getString("amap.return.code.sys.success"))) {
                // 这一类异常不应该抛上去给用户看到了, 直接返回接口调用失败, 日志HttpTools会统一记录的
                ResultCode resultCode = ResultCode.REMOTE_SERVICE_FAIL;
                throw new RemoteServiceException(resultCode.getCode(), resultCode.getMessage());
            } else {
                String bizCode = json.getString("infocode");
                if (!bizCode.equals(config.getString("amap.return.code.biz.success"))) {
                    String message = config.getString("amap.return.code." + bizCode);
                    if (message == null) {
                        // amap.return.code.300**
                        String bakCode = bizCode.substring(0, bizCode.length() - 2) + "**";
                        message = config.getString("amap.return.code." + bakCode);
                    }
                    throw new RemoteServiceException(status, message);
                } else {
                    KeyedHttpUrl khurl = (KeyedHttpUrl) hurl;
                    String fieldName = config.getString(khurl.getKey() + ".field");
                    ResponseMessage result = new ResponseMessage();
                    result.setBody(getFieldValue(json, fieldName));
                    return result;
                }
            }

        }

    }

    private static Object getFieldValue(JSONObject json, String field) {
        if ("this".equals(field)) {
            return json;
        } else if (field.contains(".")) {
            try {
                return Ognl.getValue(field, json);
            } catch (OgnlException e) {
                return null;
            }
        } else {
            return json.get(field);
        }
    }
}
